configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bin/compilation_config.cppm.in ${CMAKE_CURRENT_SOURCE_DIR}/bin/compilation_config.cppm)

### Infinity

file(GLOB_RECURSE
        main_cpp
        CONFIGURE_DEPENDS
        bin/infinity_main.cpp
)

file(GLOB_RECURSE
        main_cppm
        CONFIGURE_DEPENDS
        bin/*.cppm
)

file(GLOB_RECURSE
        infinity_cpp
        CONFIGURE_DEPENDS
        main/*.cpp
)
list(FILTER infinity_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        infinity_impl_cpp
        CONFIGURE_DEPENDS
        main/*_impl.cpp
)

file(GLOB_RECURSE
        infinity_cppm
        CONFIGURE_DEPENDS
        main/*.cppm
)

file(GLOB_RECURSE
        network_cpp
        CONFIGURE_DEPENDS
        network/*.cpp
)
list(FILTER network_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        network_impl_cpp
        CONFIGURE_DEPENDS
        network/*_impl.cpp
)

file(GLOB_RECURSE
        network_cppm
        CONFIGURE_DEPENDS
        network/*.cppm
)

file(GLOB_RECURSE
        function_cpp
        CONFIGURE_DEPENDS
        function/*.cpp
)
list(FILTER function_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        function_impl_cpp
        CONFIGURE_DEPENDS
        function/*_impl.cpp
)

file(GLOB_RECURSE
        function_cppm
        CONFIGURE_DEPENDS
        function/*.cppm
)

file(GLOB_RECURSE
        expression_cpp
        CONFIGURE_DEPENDS
        expression/*.cpp
)
list(FILTER expression_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        expression_impl_cpp
        CONFIGURE_DEPENDS
        expression/*_impl.cpp
)

file(GLOB_RECURSE
        expression_cppm
        CONFIGURE_DEPENDS
        expression/*.cppm
)

file(GLOB_RECURSE
        executor_cpp
        CONFIGURE_DEPENDS
        executor/*.cpp
)
list(FILTER executor_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        executor_impl_cpp
        CONFIGURE_DEPENDS
        executor/*_impl.cpp
)

file(GLOB_RECURSE
        executor_cppm
        CONFIGURE_DEPENDS
        executor/*.cppm
)

file(GLOB_RECURSE
        metrics_cpp
        CONFIGURE_DEPENDS
        metrics/*.cpp
)
list(FILTER metrics_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        metrics_impl_cpp
        CONFIGURE_DEPENDS
        metrics/*_impl.cpp
)

file(GLOB_RECURSE
        metrics_cppm
        CONFIGURE_DEPENDS
        metrics/*.cppm
)

file(GLOB_RECURSE
        planner_cpp
        CONFIGURE_DEPENDS
        planner/*.cpp
)
list(FILTER planner_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        planner_impl_cpp
        CONFIGURE_DEPENDS
        planner/*_impl.cpp
)

file(GLOB_RECURSE
        planner_cppm
        CONFIGURE_DEPENDS
        planner/*.cppm
)

file(GLOB_RECURSE
        scheduler_cpp
        CONFIGURE_DEPENDS
        scheduler/*.cpp
)
list(FILTER scheduler_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        scheduler_impl_cpp
        CONFIGURE_DEPENDS
        scheduler/*_impl.cpp
)

file(GLOB_RECURSE
        scheduler_cppm
        CONFIGURE_DEPENDS
        scheduler/*.cppm
)

file(GLOB_RECURSE
        storage_cpp
        CONFIGURE_DEPENDS
        storage/*.cpp
)
list(FILTER storage_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        storage_impl_cpp
        CONFIGURE_DEPENDS
        storage/*_impl.cpp
)

file(GLOB_RECURSE
        storage_cppm
        CONFIGURE_DEPENDS
        storage/*.cppm
)

file(GLOB_RECURSE
        common_cpp
        CONFIGURE_DEPENDS
        common/*.cpp
)
list(FILTER common_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        common_impl_cpp
        CONFIGURE_DEPENDS
        common/*_impl.cpp
)

file(GLOB_RECURSE
        common_cppm
        CONFIGURE_DEPENDS
        common/*.cppm
)

file(GLOB_RECURSE
        parser_cppm
        CONFIGURE_DEPENDS
        parser/*.cppm
)

#file(GLOB_RECURSE
#        parser_impl_cpp
#        CONFIGURE_DEPENDS
#        parser/*_impl.cpp
#)

file(GLOB_RECURSE
        admin_cpp
        CONFIGURE_DEPENDS
        admin/*.cpp
)
list(FILTER admin_cpp EXCLUDE REGEX .*_impl.cpp)

file(GLOB_RECURSE
        admin_impl_cpp
        CONFIGURE_DEPENDS
        admin/*_impl.cpp
)

file(GLOB_RECURSE
        admin_cppm
        CONFIGURE_DEPENDS
        admin/*.cppm
)

add_library(infinity_core
        ${infinity_cpp}
        ${planner_cpp}
        ${scheduler_cpp}
        ${storage_cpp}
        ${function_cpp}
        ${expression_cpp}
        ${executor_cpp}
        ${metrics_cpp}
        ${common_cpp}
        ${admin_cpp}
        ${network_cpp}
)

target_sources(infinity_core
        PUBLIC
        FILE_SET core_cxx_modules TYPE CXX_MODULES FILES
        ${main_cppm}
        ${infinity_cppm}
        ${common_cppm}
        ${planner_cppm}
        ${scheduler_cppm}
        ${storage_cppm}
        ${parser_cppm}
        ${function_cppm}
        ${expression_cppm}
        ${executor_cppm}
        ${metrics_cppm}
        ${admin_cppm}
        ${network_cppm}

        # for cmake bug
        ${infinity_impl_cpp}
        ${planner_impl_cpp}
        ${scheduler_impl_cpp}
        ${storage_impl_cpp}
        ${function_impl_cpp}
        ${expression_impl_cpp}
        ${executor_impl_cpp}
        ${metrics_impl_cpp}
        ${common_impl_cpp}
        ${admin_impl_cpp}
        ${network_impl_cpp}
        #        ${parser_impl_cpp}
)

#if (ARCH_AARCH64)
#    set(SSE2NEON_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/sse2neon)
#
#    target_include_directories(
#            sse2neon
#            SYSTEM
#            INTERFACE ${SSE2NEON_ROOT}
#    )
#endif ()

target_include_directories(infinity_core PUBLIC ${Python3_INCLUDE_DIRS})
target_include_directories(infinity_core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(infinity_core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/parser")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/spdlog/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/zsv/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/tomlplusplus")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/newpfor")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/fastpfor/headers")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/cppjieba/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/cppjieba/deps/limonp/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/ijma/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/pgm/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/mlas")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/xor_singleheader/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/base64/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/eigen-3.4.0")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/opencc")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/minio-cpp/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/curlpp/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/curl/include")
target_include_directories(infinity_core PUBLIC "${CMAKE_SOURCE_DIR}/third_party/darts/")

add_executable(infinity
        ${main_cpp}
)

#target_sources(infinity
#        PUBLIC
#        FILE_SET core_cxx_modules TYPE CXX_MODULES FILES
#        ${network_cppm}
#)

### Parser (built after infinity_core so it can access modules)
add_subdirectory(parser)

add_dependencies(infinity miniocpp curlpp_static libcurl_static)

target_link_libraries(infinity
        PUBLIC
        infinity_core
        sql_parser
        onnxruntime_mlas
        zsv_parser
        newpfor
        fastpfor
        jma
        opencc
        #        $<IF:$<BOOL:${ARM64}>,opencc,>
        dl
        thrift::thrift
        # thriftnb::thriftnb
        libevent::core
        oatpp::oatpp
        Parquet::parquet_static
        Arrow::arrow_static
        ${JEMALLOC_STATIC_LIB}
        miniocpp.a
        # miniocpp::miniocpp
        pugixml::static
        curlpp_static
        unofficial::inih::libinih
        unofficial::inih::inireader
        libcurl_static
        OpenSSL::SSL
        OpenSSL::Crypto
        re2::re2
        absl::any absl::log absl::base absl::bits
        PCRE2::8BIT
        RocksDB::rocksdb
        simdjson::simdjson
        nlohmann_json::nlohmann_json
        CLI11::CLI11
        magic_enum::magic_enum
        roaring::roaring
        # turbo::base64
        resolv.a
        atomic.a
        ${STDCXX15EXP_STATIC}
)
target_link_directories(infinity PUBLIC "${CMAKE_BINARY_DIR}/lib")
target_link_directories(infinity PUBLIC "${CMAKE_BINARY_DIR}/third_party/minio-cpp/")
target_link_directories(infinity PUBLIC "${CMAKE_BINARY_DIR}/third_party/curlpp/")
target_link_directories(infinity PUBLIC "${CMAKE_BINARY_DIR}/third_party/curl/")
target_link_directories(infinity PUBLIC "${CMAKE_BINARY_DIR}/third_party/")

target_include_directories(infinity PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")

# if (SKBUILD)
#    add_library(embedded_infinity_ext MODULE
#            embedded_infinity_ext.cpp
#            embedded_infinity/wrap_infinity.cpp
#    )
#
#    target_sources(embedded_infinity_ext
#            PRIVATE
#            FILE_SET core_cxx_modules TYPE CXX_MODULES FILES
#            embedded_infinity/wrap_infinity.cppm
#    )

#    nanobind_compile_options(embedded_infinity_ext)
#    nanobind_link_options(embedded_infinity_ext)
#    set_target_properties(embedded_infinity_ext PROPERTIES LINKER_LANGUAGE CXX)
#    set(libname "nanobind-static-abi3")
#    nanobind_build_library(${libname})
#    nanobind_extension_abi3(embedded_infinity_ext)
#    add_dependencies(embedded_infinity_ext miniocpp curlpp_static inih libcurl_static)

#    target_link_libraries(embedded_infinity_ext PRIVATE
#            ${libname}
#            infinity_core
#            sql_parser
#            onnxruntime_mlas
#            zsv_parser
#            newpfor
#            fastpfor
#            jma
#            opencc
#            dl
#            lz4.a
#            event.a
#            oatpp.a
#            parquet.a
#            arrow.a
#            thrift.a
#            thriftnb.a
#            snappy.a
#            ${JEMALLOC_STATIC_LIB}
#            miniocpp.a
#            pugixml.a
#            curlpp_static
#            inih.a
#            libcurl_static
#            ssl.a
#            crypto.a
#            re2.a
#            pcre2-8.a
#            rocksdb.a
#            ${STDCXX15EXP_STATIC}
#    )

# WARN: python modules shall not link to static libstdc++!!!
#    target_link_options(embedded_infinity_ext PRIVATE -static-libgcc)
#    set_target_properties(embedded_infinity_ext PROPERTIES CXX_VISIBILITY_PRESET hidden)
#
#    target_link_directories(embedded_infinity_ext PUBLIC "${CMAKE_BINARY_DIR}/lib")
#    target_link_directories(embedded_infinity_ext PUBLIC "${CMAKE_BINARY_DIR}/third_party/minio-cpp/")
#    target_link_directories(embedded_infinity_ext PUBLIC "${CMAKE_BINARY_DIR}/third_party/pugixml/")
#    target_link_directories(embedded_infinity_ext PUBLIC "${CMAKE_BINARY_DIR}/third_party/curlpp/")
#    target_link_directories(embedded_infinity_ext PUBLIC "${CMAKE_BINARY_DIR}/third_party/curl/")
#    target_link_directories(embedded_infinity_ext PUBLIC "${CMAKE_BINARY_DIR}/third_party/")
#    target_link_directories(embedded_infinity_ext PUBLIC "/usr/local/openssl30/lib64")
#    nanobind_disable_stack_protector(embedded_infinity_ext)
#    nanobind_opt_size(embedded_infinity_ext)
#    nanobind_strip(embedded_infinity_ext)
#
#    install(TARGETS embedded_infinity_ext LIBRARY DESTINATION infinity_embedded)
# endif ()

### unit test

file(GLOB_RECURSE
        test_main_cpp
        CONFIGURE_DEPENDS
        unit_test/main.cpp
)

file(GLOB_RECURSE
        ut_ut
        CONFIGURE_DEPENDS
        unit_test/*_ut.cpp
)

file(GLOB_RECURSE
        ut_impl
        CONFIGURE_DEPENDS
        unit_test/*_impl.cpp
)

file(GLOB_RECURSE
        ut_mod
        CONFIGURE_DEPENDS
        unit_test/*.cppm
        unit_test/*_impl.cpp
)
add_executable(unit_test
        ${test_main_cpp}
)
target_sources(unit_test
        PRIVATE
        FILE_SET ut_cxx_modules TYPE CXX_MODULES FILES
        ${ut_mod}

        ${ut_ut}
)

set_target_properties(unit_test PROPERTIES OUTPUT_NAME test_main)
add_dependencies(unit_test miniocpp curlpp_static libcurl_static)

target_link_libraries(unit_test
        infinity_core
        GTest::gtest GTest::gtest_main
        sql_parser
        onnxruntime_mlas
        zsv_parser
        newpfor
        fastpfor
        jma
        opencc
        dl
        thrift::thrift
        # thriftnb::thriftnb
        libevent::core
        oatpp::oatpp
        Parquet::parquet_static
        Arrow::arrow_static
        ${JEMALLOC_STATIC_LIB}
        miniocpp.a
        # miniocpp::miniocpp
        pugixml::static
        curlpp_static
        unofficial::inih::libinih
        unofficial::inih::inireader
        libcurl_static
        OpenSSL::SSL
        OpenSSL::Crypto
        re2::re2
        absl::any absl::log absl::base absl::bits
        PCRE2::8BIT
        RocksDB::rocksdb
        simdjson::simdjson
        nlohmann_json::nlohmann_json
        CLI11::CLI11
        magic_enum::magic_enum
        roaring::roaring
        resolv.a
        atomic.a
        ${STDCXX15EXP_STATIC}
)

target_compile_options(unit_test PRIVATE
        -Wall
        -Wextra
        -Wno-unused-parameter
        -Wno-sign-compare
)

target_link_directories(unit_test PUBLIC "${CMAKE_BINARY_DIR}/lib")
target_link_directories(unit_test PUBLIC "${CMAKE_BINARY_DIR}/third_party/minio-cpp/")
target_link_directories(unit_test PUBLIC "${CMAKE_BINARY_DIR}/third_party/curlpp/")
target_link_directories(unit_test PUBLIC "${CMAKE_BINARY_DIR}/third_party/curl/")
target_link_directories(unit_test PUBLIC "${CMAKE_BINARY_DIR}/third_party/")

target_include_directories(unit_test PUBLIC "${CMAKE_SOURCE_DIR}/unit_test")
